package cn.piesat.scanning.service.impl;

import cn.piesat.scanning.aspect.schedulerTask.SchedulerTaskFileRecord;
import cn.piesat.scanning.dao.HtScanningMetadataDAO;
import cn.piesat.scanning.dto.HtScanningMetadataDTO;
import cn.piesat.scanning.service.DbDmsSchedulerTaskFileRecordService;
import cn.piesat.scanning.service.HtScanningMetadataService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 源数据相关服务层接口的实现类
 * @author xhl
 */
@Service("htScanningMetadataService")
public class HtScanningMetadataServiceImpl implements HtScanningMetadataService {

    @Autowired
    private HtScanningMetadataDAO htScanningMetadataDAO;

    @Autowired
    private DbDmsSchedulerTaskFileRecordService dbDmsSchedulerTaskFileRecordService;

    /**
     * 添加源数据至数据库
     * @param dto 源数据实体类
     */
    @Override
    public void addEntity(HtScanningMetadataDTO dto) {
        try{
            htScanningMetadataDAO.save(dto);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 添加源数据至数据库，同时修改任务执行记录
     * @param dto 源数据实体类
     * @param taskId 任务ID
     */
    @Override
    public void addEntity(HtScanningMetadataDTO dto,String taskId) {
        try {
            htScanningMetadataDAO.save(dto);
            dbDmsSchedulerTaskFileRecordService.dataResults(taskId,dto.getFileName(),true);
        } catch (Exception e){
            dbDmsSchedulerTaskFileRecordService.dataResults(taskId,dto.getFileName(),false);
            e.printStackTrace();
        }
    }

    @Override
    @SchedulerTaskFileRecord("dtos")
    public void addEntityBatch(List<HtScanningMetadataDTO> dtos, String taskId) {
        if (CollectionUtils.isEmpty(dtos)) {
            return;
        }
        htScanningMetadataDAO.saveAll(dtos);
    }

    @Override
    public HtScanningMetadataDTO findByFileName(String fileName) {
        return htScanningMetadataDAO.findByFileName(fileName);
    }

    @Override
    public List<HtScanningMetadataDTO> findAllByFileName(String fileName) {
        return htScanningMetadataDAO.findAllByFileName(fileName);
    }

    /**
     * 根据传感器和数据等级查询时间范围内的源数据信息
     * @param sensor 传感器
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param level 数据等级
     * @return
     */
    @Override
    public List<HtScanningMetadataDTO> listBySensorAndRangeTimeAndLevel(String sensor, String startTime, String endTime, String level) {
        return htScanningMetadataDAO.findBySensorAndDataLevelAndFileDateBetween(sensor,level,startTime,endTime);
    }

    @Override
    public String[] listFileBySensorAndRangeTimeAndLevel(String productIid, String startTime, String endTime, String level, String fileType,String timeAttribute) {
        return htScanningMetadataDAO.listFileBySensorAndRangeTimeAndLevel(productIid,startTime,endTime,level,fileType,timeAttribute);
    }

    @Override
    public List<HtScanningMetadataDTO> listBySensorAndRangeTimeAndLevelAndBand(String sensor, String startTime, String endTime, String level, String band) {
        return htScanningMetadataDAO.findBySensorAndDataLevelAndFileDateBetweenAndBands(sensor,level,startTime,endTime,band);
    }

    /**
     * 根据产品标识查询时间范围内的源数据信息
     * @param productIid 产品标识
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return
     */

    private static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");


    @Override
    public List<HtScanningMetadataDTO> listByProductIidListAndTimeRangeAndLevel(List<String> productIid, String startTime, String endTime, String level) {
        if (productIid == null || productIid.isEmpty()) {
            return new ArrayList<>();
        }
        return htScanningMetadataDAO.findByDataLevelAndProductIidInAndFileDateBetween(level,productIid,startTime,endTime);
    }

    @Override
    public List<HtScanningMetadataDTO> findByFileNameList(List<String> fileNameList) {
        if (fileNameList == null || fileNameList.isEmpty()) {
            return new ArrayList<>();
        }
        return htScanningMetadataDAO.findByFileNameIn(fileNameList);
    }

    @Override
    public Set<String> listByDate(String startTime, String endTime) {
        List<String> datalist = htScanningMetadataDAO.findFileNameByDate(startTime,endTime);
        return new LinkedHashSet<>(datalist);
    }

    @Override
    public List<HtScanningMetadataDTO> listByProductIidAndBandsAndDataLevelAndLonAndLatAndTimeRange(String productId, String bands, String dataLevel, String lon, String lat, String leftTime, String rightTime) {
        return htScanningMetadataDAO.findByProductIidAndBandsAndDataLevelAndLonAndLatAndFileDateBetween(productId,bands,
                dataLevel,lon,lat,leftTime,rightTime);
    }

    @Override
    public List<HtScanningMetadataDTO> listByBandsAndDataLevelAndRangeTime(String bands, String dataLevel, String startTime, String endTime) {
        return htScanningMetadataDAO.findByBandsAndDataLevelAndFileDateBetween(bands,dataLevel,startTime,endTime);
    }

    @Override
    public List<HtScanningMetadataDTO> regexAndDateRangeFind(String date, String regex) {
        return htScanningMetadataDAO.regexAndDateRange(date,regex);
    }

    @Override
    public void deleteOne(HtScanningMetadataDTO dto) {
        htScanningMetadataDAO.delete(dto);
    }

    @Override
    public List<HtScanningMetadataDTO> listByBandsAndDataLevelRangeTime(List<String> bandsList, String level, String leftTime, String rightTime) {
        if (bandsList == null || bandsList.isEmpty()) {
            return new ArrayList<>();
        }
        return htScanningMetadataDAO.findByBandsInAndDataLevelAndFileDateBetween(bandsList, level, leftTime, rightTime);
    }

    @Override
    public List<HtScanningMetadataDTO> findBeforeDayAndLevelListData(Integer day, List<String> levelList) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        long plus = -1 * (day - 1);
        LocalDate now = LocalDate.now();
        String lessThenTime = dtf.format(LocalDateTime.of(now.plusDays(plus), LocalTime.MIN));
        return htScanningMetadataDAO.findByFileDateBeforeAndDataLevelIn(lessThenTime,levelList);
    }

    @Override
    public List<HtScanningMetadataDTO> findAfterDayAndLevelListData(Integer day, List<String> levelList) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        long plus = -1 * day;
        LocalDate now = LocalDate.now();
        String lessThenTime = dtf.format(LocalDateTime.of(now.plusDays(plus), LocalTime.MAX));
        return htScanningMetadataDAO.findByFileDateAfterAndDataLevelIn(lessThenTime,levelList);
    }

    @Override
    public List<String> groupByViewNumber(String dataLevel, String startTime, String endTime) {
        return htScanningMetadataDAO.groupByViewNumber(dataLevel,startTime,endTime);
    }

    @Override
    public List<HtScanningMetadataDTO> listByBandListAndViewNumberAndLevel(List<String> bandList, String viewNumber, String level) {
        if (bandList == null || bandList.isEmpty()) {
            return new ArrayList<>();
        }
        return htScanningMetadataDAO.findAllByBandsInAndViewNumberAndDataLevel(bandList,viewNumber,level);
    }

    @Override
    public List<HtScanningMetadataDTO> listBySensorListAndViewNumberAndLevel(List<String> sensorList, String viewNumber, String level) {
        if (sensorList == null || sensorList.isEmpty()) {
            return new ArrayList<>();
        }
        return htScanningMetadataDAO.findAllBySensorInAndViewNumberAndDataLevel(sensorList,viewNumber,level);
    }

    @Override
    public List<HtScanningMetadataDTO> listBySensorAndViewNumberAndLevelAndTimeRange(String sensor, String viewNumber, String level, String startTime, String endTime) {
        return htScanningMetadataDAO.findBySensorAndViewNumberAndDataLevelAndFileDateBetween(sensor,viewNumber,level,startTime,endTime);
    }

    @Override
    public List<HtScanningMetadataDTO> listByFileCatalogAndDataLevelAndRangeTime(String mainMathexp, String level, String startTime, String endTime) {
        return htScanningMetadataDAO.listByFileCatalogAndDataLevelAndRangeTime(mainMathexp,level,startTime,endTime);
    }

    @Override
    public List<HtScanningMetadataDTO> findByFileCatalogAndDataLevelAndFileDate(String fileType, String dataLevel, String fileDate) {
        return htScanningMetadataDAO.findByFileCatalogAndDataLevelAndFileDate(fileType, dataLevel, fileDate);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByTaskPlanIdIn(List<String> taskPlanIds) {
        htScanningMetadataDAO.deleteByTaskPlanIdIn(taskPlanIds);
    }

    @Override
    public List<HtScanningMetadataDTO> listByBandsAndDataLevelAndProductIidAndRangeTime(String bands, String level, String productIdentify, String startTime, String endTime) {
        if(("NULL").equals(bands)){
            bands="";
        }
        if(("NULL").equals(productIdentify)){
            productIdentify = "";
        }
        return htScanningMetadataDAO.listByBandsAndDataLevelAndProductIidAndRangeTime(bands,level,productIdentify,startTime,endTime);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByFileDateIn(List<String> deleteFileDates) {
        htScanningMetadataDAO.deleteByFileDateIn(deleteFileDates);
    }

    @Override
    public List<HtScanningMetadataDTO> findByFileNameIn(List<String> existListFileName) {
        return htScanningMetadataDAO.findByFileNameIn(existListFileName);
    }

    @Override
    public List<HtScanningMetadataDTO> findByFileDateInAndDataLevel(List<String> fileDates,String dataLevel) {
        return htScanningMetadataDAO.findByFileDateInAndDataLevel(fileDates, dataLevel);
    }

    @Override
    public String findByViewNumberDistinct(String viewNumber) {
        return htScanningMetadataDAO.findByViewNumberDistinct(viewNumber);
    }

    @Override
    public List<HtScanningMetadataDTO> listByFileCatalogAndRangeTime(String mainMathexp, String startTime, String endTime) {
        return htScanningMetadataDAO.listByFileCatalogAndRangeTime(mainMathexp,startTime,endTime);
    }

    @Override
    public List<HtScanningMetadataDTO> findByFileCatalogAndFileDate(String fileCatalog, String fileDate) {
        return htScanningMetadataDAO.findByFileCatalogAndFileDate(fileCatalog,fileDate);
    }

    @Override
    public List<HtScanningMetadataDTO> findByFileCatalogAndFileDateBetween(String fileCatalog, String leftTime, String rightTime) {
        return htScanningMetadataDAO.findByFileCatalogAndFileDateBetween(fileCatalog,leftTime,rightTime);
    }

    @Override
    public List<HtScanningMetadataDTO> findByFileCatalogAndProductIidInAndDataLevelAndFileDateBetween(String fileCatalog,List<String> productIid,String dataLevel, String leftTime, String rightTime) {
        if (productIid == null || productIid.isEmpty()) {
            productIid=null;
//            return htScanningMetadataDAO.listByFileCatalogAndDataLevelAndRangeTime(fileCatalog,dataLevel,leftTime,rightTime);
        }
        return htScanningMetadataDAO.findByFileCatalogAndProductIidInAndDataLevelAndFileDateBetween(fileCatalog,productIid,dataLevel,leftTime,rightTime);
    }

    @Override
    public List<HtScanningMetadataDTO> findByFileCatalogAndProductIidInAndDataLevelAndFileDate(String fileCatalog,List<String> productIid,String dataLevel, String fileDate) {
        if (productIid == null || productIid.isEmpty()) {
            productIid=null;
//            return htScanningMetadataDAO.findByFileCatalogAndDataLevelAndFileDate(fileCatalog,dataLevel,fileDate);
        }
        return htScanningMetadataDAO.findByFileCatalogAndProductIidInAndDataLevelAndFileDate(fileCatalog,productIid,dataLevel,fileDate);
    }

    @Override
    public List<HtScanningMetadataDTO> findByMetadata(String startTime, String endTime, String level) {
        return htScanningMetadataDAO.findByMetadata(startTime, endTime, level);
    }

    @Override
    public List<HtScanningMetadataDTO> findByMetadata(String startTime, String endTime, String level,String satellite,String product) {
        return htScanningMetadataDAO.findByMetadata(startTime, endTime, level,satellite,product);
    }

    @Override
    public HtScanningMetadataDTO findOneByDate(String startTime, String level, String satellite, String product, String region) {
        return htScanningMetadataDAO.findOneByMetadata(startTime,level,satellite,product,region);
    }

    @Override
    public HtScanningMetadataDTO findOneByDate(String startTime, String level, String satellite, String product, String region, String fileName) {
        return htScanningMetadataDAO.findOneByMetadata(startTime,level,satellite,product,region,fileName);
    }

    @Override
    public HtScanningMetadataDTO findByOrbitId(String startTime, String level, String satellite, String product, String region, String fileName, String orbitId) {
        return htScanningMetadataDAO.findByOrbitId(startTime,level,satellite,product,region,fileName,orbitId);
    }

    @Override
    public HtScanningMetadataDTO findOneByDate(String startTime, String level, String satellite, String product, String region, String productMode,String moduleIid) {
        return htScanningMetadataDAO.findOneByMetadata(startTime,level,satellite,product,region,productMode,moduleIid);
    }

    @Override
    public List<HtScanningMetadataDTO> findByMetadata(String startTime, String endTime, String level, String satellite, String product, String fileType) {
        return htScanningMetadataDAO.findByMetadata(startTime,endTime,level,satellite,product,fileType);
    }

    @Override
    public HtScanningMetadataDTO findMetadataByParam(String startTime, String level, String satellite, String product, String region, String productMode,String moduleIid ,String fileType) {
        return htScanningMetadataDAO.findMetadataByParam(startTime,level,satellite,product,region,productMode,moduleIid,fileType);
    }

    @Override
    public HtScanningMetadataDTO findMeatedataByMoudel(String startTime, String level, String satellite, String product, String region, String productMode, String moduleIid, String fileType) {
        return htScanningMetadataDAO.findOneByMetadata(startTime,level,satellite,product,region,productMode,moduleIid,fileType);
    }

    @Override
    public List<HtScanningMetadataDTO> findByMetadata(String startTime, String endTime, String level,String satellite,String product,String region,String fileType) {
        return htScanningMetadataDAO.findByMetadata(startTime, endTime, level,satellite, product, region, fileType);
    }

    @Override
    public List<HtScanningMetadataDTO> findByMetadata(String startTime,String endTime,String level,String satellite,String product,String region,String productMode,String fileType) {
        return htScanningMetadataDAO.findByMetadata(startTime, endTime, level,satellite,product,region,productMode,fileType);
    }

    @Override
    public List<HtScanningMetadataDTO> findOneByDate(String startTime, String endTime, String level, String satellite, String product, String region, String productMode, String moduleIid, String fileType) {
        return htScanningMetadataDAO.findOneByMetadata(startTime,endTime,level,satellite,product,region,productMode,moduleIid,fileType);
    }

    @Override
    public List<HtScanningMetadataDTO> findOneByDate(String startTime, String endTime, String level, String satellite, String product, String productMode, String moduleIid, String fileType) {
        return htScanningMetadataDAO.findOneByMetadataNoRegion(startTime,endTime,level,satellite,product,productMode,moduleIid,fileType);
    }

    @Override
    public List<HtScanningMetadataDTO> findListLikeProductMode(String startTime, String level, String satellite, List<String> product, String region, String productMode, String moduleIid, String fileType) {
        return htScanningMetadataDAO.findListLikeProductMode(startTime,level,satellite,product,region,productMode,moduleIid,fileType);
    }

    @Override
    public HtScanningMetadataDTO findMetaDataDto(String startTime, String level, String satellite, String product, String region, String fileType, String moduleIid) {
        return htScanningMetadataDAO.findMetaDataDto(startTime,level,satellite,product,region,fileType,moduleIid);
    }

    @Override
    public LinkedList<HtScanningMetadataDTO> findMetaDataDto(String startTime, String level, String satellite, String product, String region, String fileType) {
        return htScanningMetadataDAO.findMetaDataDto(startTime,level,satellite,product,region,fileType);
    }

    @Override
    public List<HtScanningMetadataDTO> findByMetadata(List<String> startTime, String level, String satellite, String product, String region, String fileType) {
        return htScanningMetadataDAO.findByMetadata(startTime, level,satellite, product, region, fileType);
    }

    @Override
    public HtScanningMetadataDTO findGF1(String startTime, String sensor, String level, String satellite, String product, String region, String fileName) {
        return htScanningMetadataDAO.findGF1(startTime,sensor,level,satellite,product,region,fileName);
    }

    @Override
    public List<HtScanningMetadataDTO> selectByNotRegion(String startTime, String level, String satellite, String product, String productMode, String moduleIid, String fileType) {
        return htScanningMetadataDAO.selectByNotRegion(startTime,level,satellite,product,productMode,moduleIid,fileType);
    }

    @Override
    public List<HtScanningMetadataDTO> findQxSite(String startTime, String endTime, String level, String satellite, String product, String region, String fileType) {
        return htScanningMetadataDAO.findQxSite(startTime,endTime,level,satellite,product,region,fileType);
    }

    @Override
    public List<HtScanningMetadataDTO> findBySensor(String startTime, String endTime, String level, String satellite, String product, String region, String fileType, String sensor) {
        return htScanningMetadataDAO.findBySensor(startTime,endTime,level,satellite,product,region,fileType,sensor);
    }

    @Override
    public List<Object[]> findRegionAndFilePath(String startTime, String endTime, String level, String satellite, String product, String fileType) {
        return htScanningMetadataDAO.findRegionAndFilePath(startTime,endTime,level,satellite,product,fileType);
    }


}
